package org.deltaset.meta.internal;

import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.deltaset.meta.Catalog;

/**
 *
 * @author dmakariev
 */
class CatalogBuilder {
    private static final Logger logger = Logger.getLogger(CatalogBuilder.class.getName());
    private Map<String, String> templateMap;
    private String unsuportedTemplateSrc;
    private String metaType;

    private CatalogBuilder() {
        templateMap = new HashMap<String, String>();
    }

    static CatalogBuilder newInstance() {
        return new CatalogBuilder();
    }

    CatalogBuilder map(final Map<String, String> map) {
        for (final Map.Entry<String, String> entry : map.entrySet()) {
            templateMap.put(entry.getKey(), entry.getValue());
        }
        return this;
    }

    CatalogBuilder map(Properties properties) {
        final Map<String, String> map = convertProperties(properties);
        return this.map(map);
    }

    CatalogBuilder unsuportedTemplateSrc(String templateSrc) {
        this.unsuportedTemplateSrc = templateSrc;
        return this;
    }
    
    CatalogBuilder metaType(String metaType) {
        this.metaType = metaType;
        return this;
    }

    CatalogBuilder useResource(String resourcePath) {
        final Properties p = loadByPath(resourcePath);
        return this.map(p);
    }

    Catalog build() {
        return new CatalogImpl(templateMap, unsuportedTemplateSrc,metaType);
    }

    private static Map<String, String> convertProperties(Properties properties) {
        final Map<String, String> map = new HashMap<String, String>();
        for (final Map.Entry<Object, Object> entry : properties.entrySet()) {
            final String key = (String) entry.getKey();
            final String value = (String) entry.getValue();
            map.put(key, value);
        }
        return map;
    }

    private static Properties loadByPath(final String resourcePath) {
        try {
            final Properties mergedCatalogs = new Properties();
            //if there are repeated keys, the result is not determined. (no order for loading the catalogs)            
            final Enumeration<URL> catalogs = CatalogImpl.class.getClassLoader().getResources(resourcePath);          
            logger.log(Level.INFO, "resourcePath={0}", resourcePath);
            logger.log(Level.FINER, "catalogs.hasMoreElements()={0}", catalogs.hasMoreElements());
            int count=0;
            while(catalogs.hasMoreElements()){
                final URL url = catalogs.nextElement();
                mergedCatalogs.load(url.openStream());                
                count++;
                logger.log(Level.INFO, "url[{0}]={1}", new Object[]{count, url});
                logger.log(Level.FINER, " mergedCatalogs[{0}]={1}", new Object[]{count, mergedCatalogs});
            }         
            return mergedCatalogs;
        } catch (IOException ex) {
            logger.log(Level.SEVERE, "Could not load resource=" + resourcePath,ex);
            throw new IllegalArgumentException("Could not load resource=" + resourcePath, ex);            
        }
    }
}
